package client;

import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * class Input handles all input from the user
 * 
 * @author Rasmus Stjerne, Joachim Lindholm, Daniel Gramstrup, Pamela Pedersen
 */
public class Input {
	private Scanner input; // reads data from the command line
	private Display display; // object of Display to display messages

	/**
	 * no-argument constructor initializes the Scanner
	 */
	public Input() {
		input = new Scanner(System.in);
		display = new Display();
	}

	/**
	 * method to get a String input
	 * 
	 * @return
	 */
	public String getString() {
		return input.next();
	}

	/**
	 * Handles integer input from the user.
	 * 
	 * @param lowerBounds
	 *            used to set the lowest possible input
	 * @param higherBounds
	 *            used to set the highest possible input
	 * @return
	 */
	public int getInt(int lowerBounds, int higherBounds) {
		int tal = -1;
		// creates the variable and makes sure that it is out of range
		do {
			try {
				tal = input.nextInt();
				if (tal > higherBounds || tal < lowerBounds) {
					display.displayErrorMessage("Invalid number. Number must be between "
							+ lowerBounds + "-" + higherBounds);
				}
			} catch (InputMismatchException ex) {
				display.displayErrorMessage("Invalid input. Input must be between "
						+ lowerBounds + "-" + higherBounds);
				input.next();
			}
		} while (tal > higherBounds || tal < lowerBounds);
		return tal;
	}

	/**
	 * Checks whether or not the user transfers to a valid user. Users cannot
	 * transfer to themselves.
	 * 
	 * @param currentAccountName
	 *            the sender of the transfer
	 * @param connection
	 *            to allow this method to connect to the server
	 * @return a valid recipient for the transfer
	 */
	public String getRecipient(String currentAccountName, Connection connection) {
		String recipient = input.next();
		boolean accountExists = connection.checkAccountExists(recipient);

		while (recipient.equals(currentAccountName) || !accountExists) {
			if (recipient.equals(currentAccountName)) {
				display.displayErrorMessage("You cannot transfer to yourself");
			} else if (!accountExists) {
				display.displayErrorMessage("You must enter an existing user ID");
			}
			recipient = input.next();
			accountExists = connection.checkAccountExists(recipient);
		}
		return recipient;
	}

	/**
	 * method to handle double input from the user.
	 * 
	 * @param lowerBounds
	 *            used to set the lowest possible input
	 * @param higherBounds
	 *            used to set the highest possible input
	 * @return
	 */
	public double getDouble(int lowerBounds, double higherBounds) {
		double tal = lowerBounds - 1;
		do {
			try {
				tal = input.nextDouble();
				if (tal > higherBounds || tal < lowerBounds) {
					display.displayErrorMessage("Invalid number. Number must be between "
							+ lowerBounds + "-" + higherBounds);
				}
			} catch (InputMismatchException ex) {
				display.displayErrorMessage("Invalid input. Input must be between "
						+ lowerBounds + "-" + higherBounds);
				input.next();
			}
		} while (tal > higherBounds || tal < lowerBounds);
		return tal;
	}

	/**
	 * Filters the input to match to an IP address.
	 * 
	 * @return the Ip of the server to connect to
	 */
	public String getServerIp() {
		String regex = "(^[\\d]{1,3}[\\.][\\d]{1,3}[\\.][\\d]{1,3}[\\.][\\d]{1,3})$";
		Pattern pattern = Pattern.compile(regex);

		display.displayMessage("Type the server ip you want to connect to: ");
		String serverIp = this.getString();

		Matcher matcher = pattern.matcher(serverIp);
		boolean validIp = false;

		while (!validIp) {
			if (matcher.matches()) {
				if (checkRange(serverIp)) {
					System.out.print("Invalid ip address please try again: ");
					serverIp = getString();
					matcher = pattern.matcher(serverIp);
				} else {
					validIp = true;
				}
			} else if (serverIp.equals("localhost")) {
				validIp = true;
			} else {
				System.out.print("Invalid ip address please try again: ");
				serverIp = getString();
				matcher = pattern.matcher(serverIp);
			}
		}
		return serverIp;
	}

	/**
	 * Checks the range of each of the numbers in the Ip address. They must be
	 * within 0 and 255.
	 * 
	 * @param serverIp
	 *            the IP to check
	 * @return true if each of the IP's numbers is in range of 0 and 255
	 */
	private boolean checkRange(String serverIp) {
		String[] serverIpArray = serverIp.split("\\.");
		for (int i = 0; i < serverIpArray.length; i++) {
			if (Integer.parseInt(serverIpArray[i]) < 0
					|| Integer.parseInt(serverIpArray[i]) > 255) {
				return true;
			}
		}
		return false;
	}
}